package iris_controller

import (
	"fmt"
	"github.com/kataras/iris/v12"
	domain "gluenet/internal/glue-srvp/domain"
	"gluenet/internal/glue-srvp/domain/vo"
	"gluenet/internal/pkg/infra"
	"gluenet/internal/pkg/infra/prepare"
	"gluenet/pkg/log"
	"strconv"
	"strings"
)

func init() {
	prepare.RegisterAuthController(func() {
		controller := NewConfigController()
		prepare.InjectAuthController(func() *Config {
			return controller
		})
	})
}

type Config struct {
	Config *domain.Config
}

func NewConfigController() *Config {
	r := &Config{}
	prepare.FetchDependency(&r.Config)
	return r
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/config/all
func (c *Config) GetAll(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	objs, err := c.Config.FindBy(auth, nil)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(objs)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/config/query
func (c *Config) GetQuery(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var query = make(map[string]interface{}, len(ctx.URLParams()))
	for k, v := range ctx.URLParams() {
		query[k] = v
	}
	objs, err := c.Config.FindBy(auth, query)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(objs)
}

// Create serves
// Method:   POST
// Resource: http://localhost:8080/apis/config/create/kube
func (c *Config) PostCreateKube(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.CreateConfigReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}

	cfg, err := c.Config.Create(auth, req)
	if err != nil {
		return infra.ResponseReqErr(fmt.Errorf("create file %v", err), nil)
	}
	return infra.ResponseOK(cfg)
}

// Create serves
// Method:   POST
// Resource: http://localhost:8080/apis/config/create/helm
func (c *Config) PostCreateHelm(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.CreateConfigReq{}
	fileUploads, info, err := ctx.FormFile("file")
	if err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read file %v", err), nil)
	}
	if fileUploads == nil {
		log.Warnf("file is nil")
	}
	defer fileUploads.Close()

	pIds := ctx.URLParam("ids")
	var ids []int64
	if len(pIds) > 0 {
		idstr := strings.Split(pIds, ",")
		ids = make([]int64, len(idstr))
		for k, v := range idstr {
			ids[k], err = strconv.ParseInt(v, 10, 64)
			if err != nil {
				return infra.ResponseReqErr(err, nil)
			}
		}
	}

	req.FileName = info.Filename
	req.FileReader = fileUploads
	req.Kind = infra.ConfigKindHelmChart
	req.Tags = ids
	req.Property = infra.PropertyApplication

	cfg, err := c.Config.Create(auth, req)
	if err != nil {
		return infra.ResponseReqErr(fmt.Errorf("create file %v", err), nil)
	}
	return infra.ResponseOK(cfg)
}

// Get serves
// Method:   DELETE
// Resource: http://localhost:8080/apis/config/delete
func (c *Config) DeleteDelete(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = map[string][]int64{}
	err := ctx.ReadJSON(&req)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	if _, ok := req["ids"]; !ok {
		return infra.ResponseReqErr(fmt.Errorf("need ids"), nil)
	}

	for _, id := range req["ids"] {
		if _, err = c.Config.Delete(auth, int64(id)); err != nil {
			return infra.ResponseReqErr(fmt.Errorf("delete %d %v", id, err), nil)
		}
	}
	return infra.ResponseOK(nil)
}

// Create serves
// Method:   POST
// Resource: http://localhost:8080/apis/config/update
func (c *Config) PostUpdate(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.UpdateConfigReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(err, nil)
	}

	cfg, err := c.Config.Update(auth, req)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(cfg)
}
